package com.piece.mall.service;

import com.piece.core.framework.enums.sql.SqlKey;
import com.piece.core.framework.support.bootstrap.Order;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.object.ObjectUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.jpa.repository.BaseService;
import com.piece.file.client.FileClientFactory;
import com.piece.file.model.TbSysFile;
import com.piece.file.service.TbSysFileService;
import com.piece.mall.model.PmsSkuImages;
import com.piece.mall.model.PmsSkuInfo;
import com.piece.mall.model.PmsSpuImages;
import com.piece.mall.repository.PmsSkuImagesRepository;
import com.piece.mall.vo.SkuInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class PmsSkuImagesService extends BaseService<PmsSkuImages, String> {

    @Autowired
    private PmsSkuImagesRepository pmsSkuImagesRepository;

    @Lazy
    @Resource
    private PmsSkuInfoService pmsSkuInfoService;

    @Resource
    private TbSysFileService tbSysFileService;

    @Autowired
    private FileClientFactory fileClientFactory;

    @PostConstruct
    public void initRepository() {
        setRepository(pmsSkuImagesRepository);
    }

    public List<PmsSkuImages> findImagesBySku(Long skuId) {
        return pmsSkuImagesRepository.findByCondition("skuId", skuId, Arrays.asList(new Order("imgSort", SqlKey.ASC)));
    }

    /**
     * 保存sku图片列表
     */
    public void saveSkuImages(SkuInfoVo skuVo) throws Exception {
        AtomicInteger index = new AtomicInteger(0);
        List<PmsSkuImages> skuImages = skuVo.getImages().stream().filter(image -> !StringUtil.isEmpty(image.getImgUrl()))
            .map(image -> {
                PmsSkuImages skuImage = new PmsSkuImages();
                skuImage.setSkuId(skuVo.getSkuId());
                skuImage.setImgUrl(image.getImgUrl());
                skuImage.setDefaultImg(image.getDefaultImg());
                skuImage.setImgSort(Convert.toLong(skuVo.getImages().indexOf(image), 0L));
                return skuImage;
            }).collect(Collectors.toList());
        dealWithImages(skuVo.getSkuId(), skuImages, null);
    }

    /**
     * 保存sku图片列表
     */
    public void updateSkuImages(SkuInfoVo skuVo) throws Exception {
        List<String> deleteFiles = new ArrayList<>();
        AtomicInteger index = new AtomicInteger(0);
        List<PmsSkuImages> skuImages = skuVo.getImages().stream().map(image -> {
                if (StringUtil.isEmpty(image.getImgUrl()) && null != image.getId()) {
                    deleteFiles.add(image.getId() + "");
                    return null;
                } else if (StringUtil.isNotEmpty(image.getImgUrl())) {
                    PmsSkuImages skuImage = new PmsSkuImages();
                    skuImage.setId(image.getId());
                    skuImage.setSkuId(skuVo.getSkuId());
                    skuImage.setImgUrl(image.getImgUrl());
                    skuImage.setDefaultImg(image.getDefaultImg());
                    skuImage.setImgSort(Convert.toLong(index.incrementAndGet(), 0L));
                    return skuImage;
                } else {
                    return null;
                }
            }).filter(Objects::nonNull).collect(Collectors.toList());
        dealWithImages(skuVo.getSkuId(), skuImages, deleteFiles);
    }

    /**
     * 删除sku图片列表
     */
    public void deleteSkuImages(Long skuId) {
        PmsSkuInfo skuInfo = pmsSkuInfoService.findById(skuId);
        if (null != skuInfo) {
            List<PmsSkuImages> images = findImagesBySku(skuId);
            List<String> deleteFiles = images.stream().map(image -> image.getId().toString()).collect(Collectors.toList());
            pmsSkuImagesRepository.delete(Convert.toLongList(deleteFiles).toArray(new Long[(deleteFiles.size())]));
            try {
                tbSysFileService.deleteByTableAndBusinessList(PmsSpuImages.class.getSimpleName(), deleteFiles);
            } catch (Exception e) {
                log.error("删除文件失败", e);
            }
        }
    }

    private void dealWithImages(Long skuId, List<PmsSkuImages> skuImages, List<String> deleteFiles) {
        // 删除历史数据
        if (CollectionUtils.isNotEmpty(deleteFiles)) {
            pmsSkuImagesRepository.delete(Convert.toLongList(deleteFiles).toArray(new Long[(deleteFiles.size())]));
            try {
                tbSysFileService.deleteByTableAndBusinessList(PmsSkuImages.class.getSimpleName(), deleteFiles);
            } catch (Exception e) {
                log.error("删除文件失败", e);
            }
        }

        // 更新数据
        List<PmsSkuImages> updateImages = skuImages.stream().filter(image -> null != image.getId()).collect(Collectors.toList());
        pmsSkuImagesRepository.batchUpdate(updateImages);

        // 创建数据
        List<PmsSkuImages> insertImages = skuImages.stream().filter(image -> null == image.getId()).collect(Collectors.toList());
        insertImages = pmsSkuImagesRepository.batchInsert(insertImages);

        // 维护文件表关联数据
        List<TbSysFile> files = new ArrayList<>();
        insertImages.stream().forEach(image -> {
            TbSysFile file = tbSysFileService.findById(image.getImgUrl());
            if (null != file && StringUtil.isNotEmpty(file.getBusinessId())) {
                file.setTable(PmsSkuImages.class.getSimpleName());
                file.setBusinessId(image.getId() + "");
                files.add(file);
            }
        });
        if (ObjectUtil.isNotEmpty(files)) {
            try {
                tbSysFileService.batchUpdate(files);
            } catch (Exception e) {
                log.error("更新文件失败", e);
            }
        }
    }
}
